package com.hollowlatte.manage.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hollowlatte.common.utils.Result;
import com.hollowlatte.manage.entity.Role;
import com.hollowlatte.manage.entity.User;
import com.hollowlatte.manage.entity.vo.UserVO;
import com.hollowlatte.manage.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author Hollow Latte
 * @since 2021-04-27
 */
@RequiresRoles("admin")
@Tag(name = "UserController", description = "用户管理")
@CrossOrigin
@RestController
@RequestMapping("/user")
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }


    @Operation(summary = "添加用户并分配角色", description = "若无指定密码，则密码默认为123456")
    @PostMapping("")
    public Result addUserAndAssignRoles(@RequestBody UserVO userVO) {
        List<Long> roleIdList = userVO.getRoleIdList();
        boolean affect = false;
        if (!CollectionUtils.isEmpty(roleIdList)) {
            if (StringUtils.isEmpty(userVO.getPassword())) {
                userVO.setPassword("123456");
            }
            affect = userService.saveUser(userVO.getId(), userVO.getPassword());
            for (Long roleId : roleIdList) {
                affect = userService.assignRoleForUser(userVO.getId(), roleId);
            }
        }

        if (affect) {
            return Result.ok();
        } else {
            return Result.error();
        }
    }


    @Operation(summary = "为用户分配角色")
    @PostMapping("role")
    public Result assignRoleForUser(@RequestBody UserVO userVO) {
        boolean affect = false;
        if (!CollectionUtils.isEmpty(userVO.getRoleIdList())) {
            for (Long roleId : userVO.getRoleIdList()) {
                affect = userService.assignRoleForUser(userVO.getId(), roleId);
            }
        }

        if (affect) {
            return Result.ok();
        } else {
            return Result.error();
        }
    }


    @Operation(summary = "删除用户并清除分配给该用户的所有角色")
    @DeleteMapping("")
    public Result deleteUser(@RequestParam Long userId) {
        boolean affect = userService.removeUser(userId);

        if (affect) {
            return Result.ok();
        } else {
            return Result.error();
        }
    }


    @Operation(summary = "删除用户指定角色")
    @DeleteMapping("role")
    public Result deleteRoleOfUser(@RequestBody UserVO userVO) {
        Long userId = userVO.getId();
        boolean affect = false;
        if (!CollectionUtils.isEmpty(userVO.getRoleIdList())) {
            for (Long roleId : userVO.getRoleIdList()) {
                affect = userService.removeRoleOfUser(userId, roleId);
            }
        }

        if (affect) {
            return Result.ok();
        } else {
            return Result.error();
        }
    }


    @Operation(summary = "修改用户的角色")
    @PutMapping("")
    public Result modifyRoleForUser(@RequestBody UserVO userVO) {
        Long userId = userVO.getId();
        List<Long> newRoleIdList = userVO.getRoleIdList();

        boolean affect = false;
        if (!CollectionUtils.isEmpty(newRoleIdList)) {
            affect = userService.updateRoleForUser(userId, newRoleIdList);
        }

        if (affect) {
            return Result.ok();
        } else {
            return Result.error();
        }
    }


    @Operation(summary = "分页查询")
    @GetMapping("pagination")
    public Result paging(@RequestParam Long current, @RequestParam Long size) {
        Page<User> userPage = new Page<>(current, size);
        userService.page(userPage, null);

        Page<UserVO> userVOPage = new Page<>();
        BeanUtils.copyProperties(userPage, userVOPage);

        userVOPage.setRecords(userService.convertUserToUserVO(userPage.getRecords()));

        return Result.ok().data("pageInfo", userVOPage);
    }


    @Operation(summary = "按角色分页查询", description = "roleIdList为null时，查询所有")
    @PostMapping("pagination")
    public Result multiConditionPaging(@RequestParam Long current, @RequestParam Long size, @RequestBody(required = false) UserVO userVO) {
        List<Long> roleIdList = userVO.getRoleIdList();
        List<Long> userIdList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(roleIdList)) {
            for (User user : userService.list()) {
                List<Long> resultRoleIdList = userService.listRoleById(user.getId())
                        .stream()
                        .map(Role::getId)
                        .collect(Collectors.toList());
                if (roleIdList.size() > 1) {
                    if (org.apache.commons.collections.CollectionUtils.isEqualCollection(roleIdList, resultRoleIdList)) {
                        userIdList.add(user.getId());
                    }
                } else {
                    if (resultRoleIdList.containsAll(roleIdList)) {
                        userIdList.add(user.getId());
                    }
                }
            }
        }

        Page<User> userPage = new Page<>(current, size);
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();

        if (!CollectionUtils.isEmpty(userIdList)) {
            userQueryWrapper.clear();
            userQueryWrapper.in("id", userIdList);
        } else {
            userQueryWrapper.eq("id", -1);
        }
        userService.page(userPage, userQueryWrapper);

        Page<UserVO> userVOPage = new Page<>();
        BeanUtils.copyProperties(userPage, userVOPage);

        userVOPage.setRecords(userService.convertUserToUserVO(userPage.getRecords()));

        return Result.ok().data("pageInfo", userVOPage);
    }
}

